import axios, { AxiosInstance } from 'axios';
import { Transaction, ChainType } from '@/types';
import { createModuleLogger } from '@/utils/logger';
import { PriceService } from '@/services/price/PriceService';
import { AddressLabelService } from '@/services/address/AddressLabelService';
import { ConfigService } from '@/services/config/ConfigService';
import config from '@/config';
import { ChainMonitorConfig } from '@/services/config/ChainMonitorConfigService';

const logger = createModuleLogger('bitcoin-monitor');

// 比特币相关接口定义
interface BitcoinBlock {
  id: string;
  height: number;
  timestamp: number;
  tx_count: number;
  // 注意：交易ID列表需要通过单独的API调用获取 /block/{hash}/txids
}

interface BitcoinTransaction {
  txid: string;
  version: number;
  locktime: number;
  vin: Array<{
    txid?: string;
    vout?: number;
    prevout?: {
      scriptpubkey_address?: string;
      value: number;
    };
  }>;
  vout: Array<{
    scriptpubkey_address?: string;
    value: number;
  }>;
}

export class BitcoinMonitor {
  private httpClient: AxiosInstance;
  private isRunning = false;
  private lastProcessedBlock = 0;
  private lastSuccessfulBlock = 0;
  private onTransactionCallback?: (transaction: Transaction) => void;
  private priceService: PriceService;
  private addressLabelService?: AddressLabelService;
  private configService: ConfigService | null = null;
  private consecutiveErrors = 0;
  private maxConsecutiveErrors = 5;
  private backfillInProgress = false;
  private requestDelay = 2000; // 2秒延迟，比特币区块较慢
  private chainConfig: ChainMonitorConfig | null = null;

  constructor() {
    this.priceService = PriceService.getInstance();
    
    // 创建HTTP客户端（比特币使用REST API）
    this.httpClient = axios.create({
      baseURL: 'https://blockstream.info/api',
      timeout: 10000, // 减少到10秒超时
      validateStatus: () => true
    });
  }

  // 设置交易回调
  public setTransactionCallback(callback: (transaction: Transaction) => void): void {
    this.onTransactionCallback = callback;
  }

  // 设置地址标记服务
  public setAddressLabelService(service: AddressLabelService): void {
    this.addressLabelService = service;
  }

  // 设置配置服务
  public setConfigService(configService: ConfigService): void {
    this.configService = configService;
  }

  public setChainConfig(chainConfig: ChainMonitorConfig): void {
    this.chainConfig = chainConfig;
    logger.info(`🔧 BitcoinMonitor 配置已更新: min=$${chainConfig.minValueUsd}`);
    
    // 更新请求延迟
    this.requestDelay = chainConfig.requestDelay || 2000;
    
    // 更新API端点
      this.httpClient = axios.create({
        baseURL: chainConfig.rpcUrl,
        timeout: 10000,
        validateStatus: () => true
      });
      logger.info(`🔄 BitcoinMonitor API端点已更新: ${chainConfig.rpcUrl}`);
  }

  // 获取最小交易金额阈值
  private getMinTransactionValue(): number {
    if (this.chainConfig) {
      return this.chainConfig.minValueUsd;
    }

    if (this.configService) {
      const monitoringConfig = this.configService.getMonitoringConfig();
      return monitoringConfig.minTransactionValue;
    }
    return config.monitoring.defaultMinValue; // 回退到静态配置
  }

  // 启动监控
  public async start(): Promise<void> {
    if (this.isRunning) {
      logger.warn('⚠️ 比特币监控已在运行中，跳过启动');
      return;
    }

    try {
      logger.info('🚀 正在初始化比特币监控器...');
      
      // 测试API连接 - 显示实际使用的API端点
      const actualApiUrl = this.chainConfig?.rpcUrl || 'https://blockstream.info/api';
      logger.info(`🔗 测试比特币API连接: ${actualApiUrl}`);
      this.isRunning = true;
      
      // 获取当前区块高度
      const currentHeight = await this.getCurrentBlockHeight();
      if (currentHeight) {
        // 从前一个区块开始监控，确保能处理当前区块
        this.lastProcessedBlock = currentHeight - 1;
        logger.info(`📊 比特币监控器已连接，当前区块: ${currentHeight}，从区块 ${this.lastProcessedBlock + 1} 开始监控`);
        this.startPollingMonitoring(); // 非阻塞启动
        logger.info('🔄 比特币轮询监控模式已启动');
      } else {
        this.isRunning = false;
        const errorMsg = `比特币API连接失败: ${actualApiUrl}`;
        logger.error(`❌ ${errorMsg}`);
        throw new Error(errorMsg);
      }
    } catch (error) {
      this.isRunning = false;
      const errorMsg = error instanceof Error ? error.message : String(error);
      logger.error('💥 启动比特币监控失败:', errorMsg);
      throw error; // 重新抛出错误，确保上层能正确处理
    }
  };

  // 停止监控
  public async stop(): Promise<void> {
    logger.info('⏹️ 正在停止比特币监控器...');
    this.isRunning = false;
    logger.info('✅ 比特币监控器已完全停止');
  }

  // 获取当前区块高度
  private async getCurrentBlockHeight(): Promise<number | null> {
    try {
      const response = await this.httpClient.get('/blocks/tip/height');
      
      if (response.status === 200 && typeof response.data === 'number') {
        return response.data;
      }
      logger.warn(`⚠️ Bitcoin API响应格式不正确: status=${response.status}, data=${response.data}, type=${typeof response.data}`);
      return null;
    } catch (error) {
      logger.error('获取比特币区块高度失败:', error instanceof Error ? error.message : String(error));
      return null;
    }
  }

  // 轮询监控
  private async startPollingMonitoring(): Promise<void> {
    logger.info('启动比特币轮询监控模式');
    
    while (this.isRunning) {
      try {
        const currentHeight = await this.getCurrentBlockHeight();
        
        if (currentHeight && currentHeight > this.lastProcessedBlock) {
          logger.info(`🆕 比特币发现新区块: ${this.lastProcessedBlock + 1} 到 ${currentHeight}`);
          if (this.consecutiveErrors > 0) {
            await this.backfillMissedBlocks();
            this.consecutiveErrors = 0;
          }

          // 比特币区块较少，逐个处理
          for (let height = this.lastProcessedBlock + 1; height <= currentHeight; height++) {
            if (!this.isRunning) break;
            
            try {
              await this.processBlock(height);
              this.lastProcessedBlock = height;
              this.lastSuccessfulBlock = height;
              
              // 每处理一个区块就报告进度
              logger.info(`📊 比特币监控进度: 区块 ${height}`);
              
            } catch (blockError) {
              logger.error(`处理比特币区块 ${height} 失败:`, blockError instanceof Error ? blockError.message : String(blockError));
              this.lastProcessedBlock = height;
            }
          }
        }

        this.consecutiveErrors = 0;
        
      } catch (error) {
        this.consecutiveErrors++;
        
        if (this.consecutiveErrors <= this.maxConsecutiveErrors) {
          logger.warn(`比特币轮询监控出错 (${this.consecutiveErrors}/${this.maxConsecutiveErrors}):`, error);
          
          const backoffDelay = Math.min(2000 * Math.pow(2, this.consecutiveErrors - 1), 60000);
          logger.info(`比特币等待 ${backoffDelay/1000}秒 后重试...`);
          await new Promise(resolve => setTimeout(resolve, backoffDelay));
          
        } else {
          logger.error(`比特币连续错误过多，暂停监控 60秒:`, error instanceof Error ? error.message : String(error));
          await new Promise(resolve => setTimeout(resolve, 60000));
          this.consecutiveErrors = 0;
        }
      }

      if (this.isRunning && this.consecutiveErrors === 0) {
        await new Promise(resolve => setTimeout(resolve, config.monitoring.blockCheckInterval * 2)); // 比特币出块慢，延迟加倍
      }
    }
  }

  // 区块回溯补偿
  private async backfillMissedBlocks(): Promise<void> {
    if (this.backfillInProgress || !this.isRunning) return;

    try {
      this.backfillInProgress = true;
      const currentHeight = await this.getCurrentBlockHeight();
      
      if (!currentHeight || currentHeight <= this.lastSuccessfulBlock) {
        this.backfillInProgress = false;
        return;
      }

      const missedBlocks = currentHeight - this.lastSuccessfulBlock;
      
      if (missedBlocks > 1 && missedBlocks <= 10) { // 比特币回溯10个区块
        logger.warn(`🔄 比特币检测到 ${missedBlocks} 个漏掉的区块，开始回溯补偿...`);
        
        for (let height = this.lastSuccessfulBlock + 1; height < currentHeight; height++) {
          if (!this.isRunning) break;
          
          try {
            await this.processBlock(height);
            this.lastSuccessfulBlock = height;
            await new Promise(resolve => setTimeout(resolve, 3000)); // 比特币API更慢
            
          } catch (error) {
            logger.debug(`回溯比特币区块 ${height} 失败，跳过`);
          }
        }
        
        logger.info(`✅ 比特币区块回溯完成，已补偿到区块 ${this.lastSuccessfulBlock}`);
      } else if (missedBlocks > 10) {
        logger.warn(`⚠️ 比特币漏掉区块过多 (${missedBlocks})，跳过回溯，从当前区块继续`);
        this.lastSuccessfulBlock = currentHeight - 1;
      }

    } catch (error) {
      logger.error('比特币区块回溯失败:', error instanceof Error ? error.message : String(error));
    } finally {
      this.backfillInProgress = false;
    }
  }

  // 处理比特币区块
  private async processBlock(height: number): Promise<void> {
    try {
      // 获取区块哈希
      const hashResponse = await this.httpClient.get(`/block-height/${height}`);
      if (hashResponse.status !== 200) return;

      const blockHash = hashResponse.data;
      
      // 获取区块详情（不包含交易）
      const blockResponse = await this.httpClient.get(`/block/${blockHash}`);
      if (blockResponse.status !== 200) return;

      const block: BitcoinBlock = blockResponse.data;

      logger.info(`🔍 Bitcoin区块基本信息: 高度=${block.height}, 交易数=${block.tx_count}`);
      
      // 获取区块的交易ID列表
      const txidsResponse = await this.httpClient.get(`/block/${blockHash}/txids`);
      if (txidsResponse.status !== 200) {
        logger.warn(`⚠️ 无法获取区块 ${height} 的交易列表`);
        return;
      }

      const txids: string[] = txidsResponse.data;

      // 验证数据
      if (!block || !txids || !Array.isArray(txids)) {
        logger.info(`❌ 比特币区块 ${height} 数据无效，跳过. block存在: ${!!block}, txids存在: ${!!txids}, txids是数组: ${Array.isArray(txids)}`);
        return;
      }

      // 每个区块记录进度（比特币区块较少）
      logger.info(`📊 BTC监控进度: 区块 ${height}, 交易数: ${txids.length}`);

      // 处理区块中的交易（限制数量）
      const maxTransactions = Math.min(txids.length, 20);
      
      for (let i = 0; i < maxTransactions; i++) {
        if (!this.isRunning) break;
        
        const txHash = txids[i];
        if (!txHash || typeof txHash !== 'string') {
          continue;
        }
        
        try {
          await this.processTransaction(txHash, block);
          await new Promise(resolve => setTimeout(resolve, this.requestDelay));
        } catch (error) {
          logger.error(`处理比特币交易失败 ${txHash}:`, error instanceof Error ? error.message : String(error));
        }
      }

      if (txids.length > maxTransactions) {
        logger.info(`📊 BTC区块 ${block.height}: 处理了前 ${maxTransactions}/${txids.length} 笔交易`);
      }

    } catch (error) {
      logger.error(`处理比特币区块 ${height} 失败:`, error instanceof Error ? error.message : String(error));
    }
  }

  // 处理比特币交易
  private async processTransaction(txid: string, block: BitcoinBlock): Promise<void> {
    try {
      const response = await this.httpClient.get(`/tx/${txid}`);
      
      if (response.status !== 200) {
        logger.warn(`⚠️ 获取交易详情失败: ${txid}, status=${response.status}`);
        return;
      }

      const tx: BitcoinTransaction = response.data;
      
      // 检查是否为coinbase交易（挖矿奖励）
      let isCoinbaseTransaction = false;
      if (tx.vin && tx.vin.length > 0) {
        const firstInput = tx.vin[0];
        if (firstInput && (!firstInput.txid || !firstInput.prevout)) {
          isCoinbaseTransaction = true;
        }
      }

      // 如果是coinbase交易，跳过处理（通常不是我们关心的大额转账）
      if (isCoinbaseTransaction) {
        logger.debug(`⏭️ 跳过coinbase交易: ${txid}`);
        return;
      }
      
      // 计算交易总输出金额（BTC）
      let totalOutputBTC = 0;
      let mainOutputAddress = '';
      let maxOutputValue = 0;
      let validOutputs: Array<{address: string, value: number}> = [];
      
      for (const output of tx.vout) {
        totalOutputBTC += output.value;
        // 收集有效的输出地址
        if (output.value > 0 && output.scriptpubkey_address) {
          validOutputs.push({
            address: output.scriptpubkey_address,
            value: output.value
          });
          
          // 找到最大金额的输出地址
          if (output.value > maxOutputValue) {
            maxOutputValue = output.value;
            mainOutputAddress = output.scriptpubkey_address;
          }
        }
      }

      // 获取主要输入地址
      let fromAddress = '';
      let validInputs: Array<{address: string, value: number}> = [];
      
      if (tx.vin && tx.vin.length > 0) {
        for (const input of tx.vin) {
          if (input && input.prevout && input.prevout.scriptpubkey_address) {
            validInputs.push({
              address: input.prevout.scriptpubkey_address,
              value: input.prevout.value
            });
          }
        }
        
        // 选择最大输入作为主要发送方
        if (validInputs.length > 0) {
          const maxInput = validInputs.reduce((max, input) => 
            input.value > max.value ? input : max
          );
          fromAddress = maxInput.address;
        }
      }

      // 验证地址有效性
      if (!fromAddress || !mainOutputAddress) {
        logger.debug(`⏭️ 跳过地址不完整的交易: ${txid}, from=${fromAddress}, to=${mainOutputAddress}`);
        return;
      }

      // 检查是否是自转交易（同一地址之间）
      if (fromAddress === mainOutputAddress) {
        logger.debug(`⏭️ 跳过自转交易: ${txid}, address=${fromAddress}`);
        return;
      }

      // 将satoshi转换为BTC（1 BTC = 100,000,000 satoshi）
      const valueBTC = totalOutputBTC / 100000000;
      const btcPriceUSD = await this.getBTCPrice();
      const valueUSD = valueBTC * btcPriceUSD;

      // 检查是否为大额交易
      if (valueUSD < this.getMinTransactionValue()) return;

      logger.info(`🔍 Bitcoin交易信息: from="${fromAddress}", to="${mainOutputAddress}", inputs=${validInputs.length}, outputs=${validOutputs.length}`);

      // 获取地址标签
      let fromLabel, toLabel;
      if (this.addressLabelService && fromAddress && mainOutputAddress) {
        [fromLabel, toLabel] = await Promise.all([
          this.addressLabelService.getAddressLabel(fromAddress, ChainType.BITCOIN),
          this.addressLabelService.getAddressLabel(mainOutputAddress, ChainType.BITCOIN)
        ]);
      }

      const transaction: Transaction = {
        id: `btc_${txid}`,
        hash: txid,
        chain: ChainType.BITCOIN,
        fromAddress: fromAddress || '',
        toAddress: mainOutputAddress || '',
        value: valueBTC.toString(),
        valueUsd: valueUSD,
        blockNumber: block.height,
        timestamp: new Date(block.timestamp * 1000),
        tokenSymbol: 'BTC',  // 添加代币符号
        confirmed: true,
        fromLabel: fromLabel ? fromLabel.label : undefined,
        toLabel: toLabel ? toLabel.label : undefined
      };

      let logMessage = `🔥 BTC大额交易: ${valueUSD.toLocaleString('en-US', { style: 'currency', currency: 'USD' })} (${valueBTC.toFixed(8)} BTC)`;
      if (fromLabel) {
        logMessage += `, 发送方: ${fromLabel.label} (${fromLabel.type})`;
      }
      if (toLabel) {
        logMessage += `, 接收方: ${toLabel.label} (${toLabel.type})`;
      }
      logMessage += ` | 区块: ${block.height}`;
      
      logger.warn(logMessage);

      if (this.onTransactionCallback) {
        this.onTransactionCallback(transaction);
      }

    } catch (error) {
      logger.error(`💥 处理比特币交易失败 ${txid.substring(0, 8)}:`, error instanceof Error ? error.message : String(error));
    }
  }

  // 获取BTC价格
  private async getBTCPrice(): Promise<number> {
    return await this.priceService.getTokenPrice('BTC');
  }
}